// sparkAiService.ts
// 讯飞星火AI服务模块

import CryptoJS from 'crypto-js';

/**
 * 讯飞星火AI配置
 */
const SPARK_CONFIG = {
  // 不同版本的模型地址和domain参数
  models: {
    'v4.0Ultra': {
      url: 'wss://spark-api.xf-yun.com/v4.0/chat',
      domain: '4.0Ultra'
    },
    'max-32k': {
      url: 'wss://spark-api.xf-yun.com/chat/max-32k',
      domain: 'max-32k'
    },
    'max': {
      url: 'wss://spark-api.xf-yun.com/v3.5/chat',
      domain: 'generalv3.5'
    },
    'pro-128k': {
      url: 'wss://spark-api.xf-yun.com/chat/pro-128k',
      domain: 'pro-128k'
    },
    'pro': {
      url: 'wss://spark-api.xf-yun.com/v3.1/chat',
      domain: 'generalv3'
    },
    'lite': {
      url: 'wss://spark-api.xf-yun.com/v1.1/chat',
      domain: 'lite'
    }
  }
};

/**
 * 生成鉴权URL
 * @param appId 应用ID
 * @param apiKey API密钥
 * @param apiSecret API密钥密文
 * @param model 模型版本
 * @returns 鉴权后的WebSocket URL
 */
function generateAuthUrl(appId: string, apiKey: string, apiSecret: string, model: string = 'max') {
  // 获取模型配置
  const modelConfig = SPARK_CONFIG.models[model as keyof typeof SPARK_CONFIG.models] || SPARK_CONFIG.models.max;
  
  // 生成RFC1123格式的时间戳
  const date = new Date().toUTCString();
  
  // 构建签名原始字符串
  const signatureOrigin = `host: spark-api.xf-yun.com\ndate: ${date}\nGET /${getModelPath(modelConfig.url)} HTTP/1.1`;
  
  // 使用CryptoJS进行HMAC-SHA256加密
  const signature = CryptoJS.enc.Base64.stringify(
    CryptoJS.HmacSHA256(signatureOrigin, apiSecret)
  );
  
  // 构建授权头
  const authorizationOrigin = `api_key="${apiKey}", algorithm="hmac-sha256", headers="host date request-line", signature="${signature}"`;
  const authorization = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(authorizationOrigin));
  
  // 构建最终URL
  const authUrl = `${modelConfig.url}?authorization=${authorization}&date=${date}&host=spark-api.xf-yun.com`;
  
  return authUrl;
}

/**
 * 从URL中提取路径
 * @param url 完整URL
 * @returns 路径部分
 */
function getModelPath(url: string): string {
  const match = url.match(/xf-yun\.com\/([^?#]+)$/);
  return match?.[1] ?? '';
}

/**
 * 使用讯飞星火AI分析药物相互作用
 * @param drug1 第一种药物名称
 * @param drug2 第二种药物名称
 * @param interactionDescription 相互作用描述
 * @param options 配置选项
 * @returns Promise包含AI分析结果
 */
export async function analyzeDrugInteractionWithSpark(
  drug1: string,
  drug2: string,
  interactionDescription: string,
  options: {
    appId: string;
    apiKey: string;
    apiSecret: string;
    model?: string;
  }
): Promise<string> {
  return new Promise((resolve, reject) => {
    // 获取模型配置
    const model = options.model || 'max';
    const modelConfig = SPARK_CONFIG.models[model as keyof typeof SPARK_CONFIG.models] || SPARK_CONFIG.models.max;
    
    // 生成鉴权URL
    const authUrl = generateAuthUrl(options.appId, options.apiKey, options.apiSecret, model);
    
    // 创建WebSocket连接
    const socket = new WebSocket(authUrl);
    
    let fullResponse = '';
    
    // 连接打开时发送消息
    socket.onopen = () => {
      // 构建请求参数，严格按照讯飞星火AI的格式要求
      const request = {
        header: {
          app_id: options.appId,
          uid: "ictest"
        },
        parameter: {
          chat: {
            domain: modelConfig.domain,
            temperature: 0.5,
            max_tokens: 2048
          }
        },
        payload: {
          message: {
            text: [
              {
                role: "system",
                content: "你是一名专业的临床药师，擅长药物相互作用分析。请根据提供的药物相互作用信息，生成一份专业的分析报告。"
              },
              {
                role: "user",
                content: `基于药物相互作用信息:${interactionDescription}，提供简明临床建议摘要。使用专业术语，提供可操作建议。`
              }
            ]
          }
        }
      };
      
      // 发送请求
      const requestPayload = JSON.stringify(request);
      socket.send(requestPayload);
      
      // 输出请求信息用于调试
      console.log('发送到AI服务的请求:', requestPayload);
    };
    
    // 接收消息
    socket.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data);
        console.log('收到AI服务响应:', data); // 添加调试日志
        
        // 检查是否有错误
        if (data.header.code !== 0) {
          const errorMessage = data.header.message || '未知错误';
          const errorCode = data.header.code || '未知错误码';
          
          // 特别处理10003错误
          if (errorCode === 10003) {
            reject(new Error(`AI服务错误 [${errorCode}]: ClientMsgError (客户端消息格式错误)，请检查发送的消息格式`));
          } else {
            reject(new Error(`AI服务错误 [${errorCode}]: ${errorMessage}`));
          }
          socket.close();
          return;
        }
        
        // 获取AI回复内容
        if (data.payload.choices && data.payload.choices.text) {
          const content = data.payload.choices.text[0].content;
          fullResponse += content;
        }
        
        // 检查是否是最后一次回复
        if (data.header.status === 2) {
          socket.close();
          console.log('AI服务完整响应:', fullResponse); // 添加调试日志
          resolve(fullResponse);
        }
      } catch (error) {
        console.error('解析AI回复时出错:', error);
        reject(new Error(`解析AI回复时出错: ${error instanceof Error ? error.message : '未知错误'}`));
        socket.close();
      }
    };
    
    // 连接错误处理
    socket.onerror = (error) => {
      console.error('WebSocket连接错误:', error);
      reject(new Error(`WebSocket连接错误: ${error instanceof Error ? error.message : '未知错误'}`));
    };
    
    // 连接关闭处理
    socket.onclose = (event) => {
      console.log('WebSocket连接关闭:', event); // 添加调试日志
      if (!fullResponse) {
        reject(new Error('连接已关闭但未收到有效回复'));
      }
    };
  });
}

export default {
  analyzeDrugInteractionWithSpark
};